import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转换为灰度
def load_image(image_path):
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return gray

# 绘制灰度直方图
def plot_histogram(image):
    hist = cv2.calcHist([image], [0], None, [256], [0, 256])
    plt.plot(hist, color='black')
    plt.title("Grayscale Histogram")
    plt.xlabel("Pixel Intensity")
    plt.ylabel("Frequency")
    plt.show()

# 根据阈值生成种子区域
def generate_seed_region(image, threshold):
    _, binary = cv2.threshold(image, threshold, 255, cv2.THRESH_BINARY)
    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary, connectivity=8, ltype=cv2.CV_32S)
    seeds = []
    for i in range(1, num_labels):  # 跳过背景
        if stats[i, cv2.CC_STAT_AREA] > 5:  # 筛选较小连通区域
            seed = (int(centroids[i][1]), int(centroids[i][0]))  # 注意 (y, x) 顺序
            seeds.append(seed)
    return seeds, binary

# 区域生长算法
def get_gray_diff(image, current_point, tmp_point):
    return abs(int(image[current_point[0], current_point[1]]) - int(image[tmp_point[0], tmp_point[1]]))

def regional_growth(image, seeds, thresh):
    height, width = image.shape
    seed_mark = np.zeros(image.shape, dtype=np.uint8)
    seed_list = seeds.copy()
    label = 1
    connects = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]  # 8 邻接
    while seed_list:
        current_point = seed_list.pop(0)
        seed_mark[current_point] = label
        for connect in connects:
            tmp_x = current_point[0] + connect[0]
            tmp_y = current_point[1] + connect[1]
            if tmp_x < 0 or tmp_y < 0 or tmp_x >= height or tmp_y >= width:
                continue
            gray_diff = get_gray_diff(image, current_point, (tmp_x, tmp_y))
            if gray_diff < thresh and seed_mark[tmp_x, tmp_y] == 0:
                seed_mark[tmp_x, tmp_y] = label
                seed_list.append((tmp_x, tmp_y))
    return seed_mark

# Ostu阈值分割
def otsu_threshold(image):
    _, binary = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return binary

# 主函数
def main():
    image_path = "img/XRay.png"  # 图像路径
    image = load_image(image_path)

    # 绘制直方图
    plot_histogram(image)

    # 种子区域生成
    threshold = 200  # 高亮区域的阈值，可调整
    seeds, binary_seed = generate_seed_region(image, threshold)
    print(f"生成的种子点数量: {len(seeds)}")

    # 区域生长
    growth_threshold = 15  # 灰度差阈值，可调整
    region_growth_result = regional_growth(image, seeds, growth_threshold)

    # Ostu阈值分割
    otsu_result = otsu_threshold(image)

    # 显示结果
    plt.figure(figsize=(12, 8))
    plt.subplot(221), plt.imshow(image, cmap='gray'), plt.title("Original Image")
    plt.subplot(222), plt.imshow(binary_seed, cmap='gray'), plt.title("Seed Region")
    plt.subplot(223), plt.imshow(region_growth_result, cmap='gray'), plt.title("Region Growth")
    plt.subplot(224), plt.imshow(otsu_result, cmap='gray'), plt.title("Otsu Threshold")
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    main()
